package com.flowable.project.controller;


import com.flowable.project.model.User;
import com.flowable.project.model.request.InfoBind;
import com.flowable.project.rocketmq.JmsConfig;
import com.flowable.project.service.InfoBindService;
import com.flowable.project.service.OpenApiService;
import com.flowable.project.util.JsonData;
import io.swagger.annotations.*;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricActivityInstanceQuery;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/test")
@Api(tags = "测试模块",value = "测试Controller")
public class TestController {
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private OpenApiService openApiService;

    @Autowired
    private InfoBindService infoBindService;

    private Logger log;


    @RequestMapping(value = "/upload")
    public JsonData upload(@RequestParam("file") MultipartFile file,@RequestParam("processKey") String processKey) {    //注意参数
        Deployment deploy = repositoryService.createDeployment().name("test").addBytes("aaa.bpmn20.xml", file.getBytes()).deploy();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey);
        Map<String, Object> processVariables = processInstance.getProcessVariables();
        System.out.println("流程定义id="+processInstance.getProcessInstanceId());
        System.out.println("流程实例id="+processInstance.getId());
        System.out.println("当前活动的id="+processInstance.getActivityId());
        return JsonData.buildSuccess(processVariables);
    }

    @PostMapping("/bind")
    public JsonData bindInfo(@RequestBody InfoBind infoBind){
        infoBindService.saveInfo(infoBind);
        return JsonData.buildSuccess();
    }





    @ApiOperation("成功！！！")
    @GetMapping("/success")
    public JsonData Success(){
        System.out.println("successs!!!!");
        return JsonData.buildSuccess();
    }

    @ApiOperation("添加用户")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "name", value = "123", required = true, paramType="body",dataType = "com.flowable.project.model.User"),
//    })
    @PostMapping ("/add")
    public JsonData Success(@RequestBody User user){
        return JsonData.buildSuccess(user);
    }
    @ApiOperation("用户登录")
    @PostMapping("/login")
    @ApiResponses({
            @ApiResponse(responseCode = "302",description = "重定向，跳转登录"),
            @ApiResponse(responseCode = "403",description = "没权限"),
    })
    public JsonData login(
            @ApiParam(name = "phone",value = "手机号",example = "123456789")
            @RequestParam("phone") String phone,
            @ApiParam(name = "pwd",value = "密码",example = "123456789")
            @RequestParam("pwd") String pwd){
        return JsonData.buildSuccess(phone+pwd);
    }

    @RequestMapping("/fail")
    public String Fail(){
        System.out.println("fail!!!!");
        return "fail";
    }

    @GetMapping("/start")
    public JsonData startFlow(String key) {
//        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        RepositoryService repositoryService = processEngine.getRepositoryService();
//        Deployment deploy = repositoryService.createDeployment().name("测试").addClasspathResource("processes/aaa.bpmn20.xml").deploy();
//        System.out.println("流程部署id="+deploy.getId());
//        System.out.println("流程部署name="+deploy.getName());
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);

        System.out.println("流程定义id="+processInstance.getProcessInstanceId());
        System.out.println("流程实例id="+processInstance.getId());
        System.out.println("当前活动的id="+processInstance.getActivityId());
//        List<Execution> list = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().list();= runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().list();
//        System.out.println("execution_id="+execution.getId());
//        runtimeService.setVariable(execution.getId(),"executionId",execution.getId());
//        taskService.complete("12506");

//        taskService.complete(taskId,map1);
        String processId = processInstance.getId();
        String name = processInstance.getName();
        System.out.println(processId + ":" + name);
        return JsonData.buildSuccess();
    }

    @PostMapping ("/task")
    public JsonData Task (String processDefinitionKey,String assignee) {
        List<Task> list = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
        List<Map<String,String>> list1 = new ArrayList<>();
        for (Task task:list){
            Map<String,String> map = new HashMap<>();
            System.out.println("流程实例id="+task.getProcessInstanceId());
            map.put("流程实例id",task.getProcessInstanceId());
            System.out.println("任务id="+task.getId());
            map.put("任务id",task.getId());
            System.out.println("任务负责人="+task.getAssignee());
            map.put("任务负责人",task.getAssignee());
            System.out.println("任务名称="+task.getName());
            map.put("任务名称",task.getName());
            list1.add(map);
        }
        return JsonData.buildSuccess(list1);
    }

    @GetMapping("/complete/task")
    public JsonData completeTask (String taskId) {
        taskService.complete(taskId);
        return JsonData.buildSuccess();
    }

    @GetMapping("/getProcessDefinition")
    public JsonData queryProcessDefinition(String processKey){
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processKey).orderByProcessDefinitionVersion().desc().list();
        List<Map<String,Object>> list1 = new ArrayList<>();
        for(ProcessDefinition processDefinition:list){
            Map<String,Object> map = new HashMap<>();
            map.put("流程定义ID",processDefinition.getId());
            map.put("流程定义名称",processDefinition.getName());
            map.put("流程定义Key",processDefinition.getKey());
            map.put("流程定义版本",processDefinition.getVersion());
            list1.add(map);
        }
        return JsonData.buildSuccess(list1);
    }


    @DeleteMapping ("/delete/getProcessDefinition")
    public JsonData deleteProcessDefinition(String deployId){
        repositoryService.deleteDeployment(deployId);
        //当流程没走完，需要强制删除时，使用级联删除
        //repositoryService.deleteDeployment(deployId,true);
        return JsonData.buildSuccess();
    }

    @GetMapping ("/get/deployment")
    public JsonData getDeployment(String processDefinitionKey) throws FileNotFoundException {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey).singleResult();
        String deploymentId = processDefinition.getId();
        InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
        repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
        File pngFile = new File("d:/evecton.png");
        File bpmnFile = new File("d:/evecton.bpmn");
        FileOutputStream pngOutputStream = new FileOutputStream(pngFile);
        FileOutputStream bpmnOutputStream = new FileOutputStream(bpmnFile);
        //...........
        return JsonData.buildSuccess();
    }

    @GetMapping ("/get/historyInfo")
    public JsonData getHistoryInfo(String processInstanceId){
        HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
        List<HistoricActivityInstance> list = historicActivityInstanceQuery.processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().list();
        List<Map<String,Object>> list1 = new ArrayList<>();
        for(HistoricActivityInstance historicActivityInstance:list){
            Map<String,Object> map = new HashMap<>();
            map.put("流程ID",historicActivityInstance.getProcessInstanceId());
            map.put("活动名称",historicActivityInstance.getActivityName());
            map.put("流程定义ID",historicActivityInstance.getProcessDefinitionId());
            map.put("活动ID",historicActivityInstance.getActivityId());
            list1.add(map);
        }
        return JsonData.buildSuccess(list1);
    }

    /**
     * 启动流程实例，添加businessKey
     */
    @GetMapping("/addBusinessKey")
    public JsonData addBusinessKey(String processInstanceByKey,String businessKey){
//        1、得到ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、得到RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
//        3、启动流程实例，同时还要指定业务标识businessKey，也就是出差申请单id，这里是1001
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceByKey(processInstanceByKey,businessKey);
//        4、输出processInstance相关属性
        System.out.println("业务id=="+processInstance.getBusinessKey());
        return JsonData.buildSuccess();
    }

    /**
     * 设置流程负责人
     */

    @GetMapping("/assigneeUEL")
    public void assigneeUEL(){
        Map<String,Object> assigneeMap = new HashMap<>();
        assigneeMap.put("assignee0","张三");
        assigneeMap.put("assignee1","李经理");
        assigneeMap.put("assignee2","王总经理");
//        启动流程实例，同时还要设置流程定义的assignee的值
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evection", assigneeMap);
//       输出
        System.out.println("流程定义id="+processInstance.getProcessInstanceId());
        System.out.println("流程实例id="+processInstance.getId());
        System.out.println("当前活动的id="+processInstance.getActivityId());
    }

    @GetMapping("/ok")
    public JsonData ok(String executionId) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        System.out.println(executionId);
        Message message = new Message(JmsConfig.TOPIC,"",executionId, (executionId).getBytes() );
//        payProducer.getProducer().send(message);
        return JsonData.buildSuccess(executionId+"的消息接收成功");
    }

    @GetMapping("/fail")
    public JsonData fail(String executionId) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        System.out.println(executionId);
        Message message = new Message(JmsConfig.TOPIC,"",executionId, (executionId).getBytes() );
//        payProducer.getProducer().send(message);
        return JsonData.buildError(executionId+"的消息接收失败");
    }

    @RequestMapping("/message")
    public void message(String message,String executionId){
        runtimeService.messageEventReceived(message,executionId);
        System.out.println("消息发送成功！！！");
    }

    @RequestMapping("/save/open_api_info")
    public JsonData saveOpenApiInfo(String fileName){
        openApiService.saveOpenApiInfo(fileName);
        return JsonData.buildSuccess();
    }
}
